﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZQNB.BaseLib.Core;
using ZQNB.BaseLib.Core.Models;
using ZQNB.Common.Caching;
using ZQNB.Common.Web;

namespace ZQNB.Web.Common.Helpers
{
    public class MenuHelper
    {
        private static readonly object _lock = new object();
        private static readonly Dictionary<string, IList<SideBarMenu>> _menuDic = new Dictionary<string, IList<SideBarMenu>>();
        private readonly ISideBarMenuService _menuRepository;
        private readonly ISideBarMenuRender _render;

        public MenuHelper(ISideBarMenuService menuRepository, ISideBarMenuRender render)
        {
            _menuRepository = menuRepository;
            _render = render;
        }
        
        public string MakeBreadcurmbHtml(string position)
        {
            var currentNode = GetCurrentNode(position);
            var html = _render.RenderBreadcurmbHtml(currentNode);
            return html;
        }

        public string MakeSideMenuHtml(string position)
        {
            var treeNode = GetMenuTree(position);
            var html = _render.RenderSideMenuHtml(treeNode);
            return html;
        }

        public IList<SideBarMenu> GetMenus(string position, string module)
        {
            var query = _menuRepository.GetAll(position);
            return query.OrderBy(x => x.SortNum)
                .ThenBy(x => x.Href)
                .ToList();
        }

        public MenuTreeNode GetMenuTree(string position)
        {
            //缓存这个列表
            string positionKey = position.ToLower();
            IList<SideBarMenu> menusInPosition = null;
            lock (_lock)
            {
                if (!_menuDic.ContainsKey(positionKey))
                {
                    menusInPosition = GetMenus(position, null);
                    _menuDic[positionKey] = menusInPosition;
                }
                menusInPosition = _menuDic[positionKey];
            }

            //convert
            var treeNode = MenuTreeConvertor.ConvertToPositionTree(menusInPosition);
            //replace href
            var request = MvcHelper.MakeRequest();
            ReplaceHerfSchema(treeNode, request);
            return treeNode;
        }

        public MenuTreeNode GetCurrentNode(string position)
        {
            var treeNode = GetMenuTree(position);
            var currentUrl = MvcHelper.GetCurrentUrl();
            var currentNode = FindCurrentNode(treeNode, currentUrl);
            return currentNode;
        }
        
        private void ReplaceHerfSchema(MenuTreeNode tree, NbMvcRequest request)
        {

            tree.Href = tree.Href.ToLower()
                .Replace("{area}", request.Area)
                .Replace("{controller}", request.Controller)
                .Replace("{action}", request.Controller)
                .Replace("{owner}", request.Owner); 

            foreach (var child in tree.Children)
            {
                ReplaceHerfSchema(child, request);
            }
        }

        private MenuTreeNode FindCurrentNode(MenuTreeNode tree, string currentUrl)
        {
            if (CompareUrlEqual(tree.Href, currentUrl))
            {
                return tree;
            }
            foreach (var child in tree.Children)
            {
                var result = FindCurrentNode(child, currentUrl);
                if (result != null)
                {
                    return result;
                }
            }
            return null;
        }

        private bool CompareUrlEqual(string url1, string url2)
        {
            return MvcHelper.CompareUrlEqual(url1, url2);
        }
    }
}
